#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "tme_file_fmt.h"
#include "tme_utils.h"
#include "tme_log.h"

#include "tme_api.h"

/* 用于属性名和id互相转换用的链表 */
typedef struct TME_AttrUint {
    uint32_t state; /* 预留状态码,例如找不到父属性会在此标记 */
    TME_AttrTab* attrTab; /* 属性配置 (映射文件内存) */
    TME_FatChain* timeFat; /* 属性时间表fat句柄 */
    TME_FatChain* dataFat; /* 属性数据fat句柄 */
    char* fullName; /* 属性全名 (动态分配内存) */
    struct TME_AttrUint* next;
    struct TME_AttrUint* parent; /* 指向父属性 */
} TME_AttrUint;

/* 总览时间表变化记录 */
typedef struct TME_TimeFatNote {
    uint32_t cAttrId; /* 当前属性 */
    uint32_t cFatIndex; /* 当前fat表序号 */
    uint32_t cDiffMs; /* 当前和文件创建时间的差值ms */
} TME_TimeFatNote;

/* api句柄 */
typedef struct TME_ApiHandle {
    TME_File* fp;
    TME_FatChain* attrFat; /* 总属性表fat句柄 */
    TME_FatChain* timeFat; /* 总览时间表fat句柄 */
    TME_AttrUint* attrUint; /* 当前打开的所有属性的单向链表,并且新增属性在前面 */
    TME_TimeFatNote timeFatNoteWrite; /* 用来记录时间表信息变化,以判断需要更新哪种类型信息 */
    TME_TimeFatNote timeFatNoteRead;
} TME_ApiHandle;

/* -------------------- inner -------------------- */

/* 递归拼接名称,返回buff使用长度 */
static int32_t _tme_attrNameSpilt(TME_AttrUint* attrUint, char* buff, int32_t buffSize)
{
    int32_t result = 0;
    do
    {
        /* 递归 */
        if (attrUint->parent)
        {
            result = _tme_attrNameSpilt(attrUint->parent, buff, buffSize);
            if (result >= buffSize) {
                break;
            }
            /* 添加间隔符 */
            buff[result++] = TME_ATTR_FULL_NAME_SPILT;
        }
        /* 填写当前属性名 */
        result += snprintf(&buff[result], buffSize - result, "%s", attrUint->attrTab->shortName);
    } while(0);
    return result;
}

static char* _tme_attrFullName(TME_AttrUint* attrUint)
{
    char* fullName = NULL;
    do
    {
        /* 评估总长度 */
        int32_t len = 0;
        TME_AttrUint* tmpAttrUint = attrUint;
        while (tmpAttrUint) {
            len += 1 + strlen(tmpAttrUint->attrTab->shortName);
            tmpAttrUint = tmpAttrUint->parent;
        }
        if (len <= 1) {
            TME_ERR("attr \"%s\" shortName len err", attrUint->attrTab->shortName);
            break;
        }
        /* 分配内存 */
        fullName = (char*)calloc(1, len);
        if (!fullName) {
            TME_ERR("calloc failed, size:%d", len);
            break;
        }
        /* 拼接名称 */
        _tme_attrNameSpilt(attrUint, fullName, len);
    } while(0);
    return fullName;
}

/* 加载所有attr到链表 */
static int32_t _tme_load_attrUint(TME_File* fp, TME_FatChain* attrFat, TME_AttrUint** attrUint)
{
    int32_t result = -1;
    do
    {
        if (attrFat->type != TME_FAT_UNIT_TYPE_ATTR) {
            TME_ERR("type error, %d(type) != %d(attr tab)", attrFat->type, TME_FAT_UNIT_TYPE_ATTR);
            break;
        }
        /* 根据总大小,遍历所有attr,并取得映射内存 */
        TME_AttrUint* tmpAttrUint = NULL;
        TME_AttrUint* tmpAttrUint2 = NULL;
        TME_AttrTab* tmpAttrTab = NULL;
        int32_t offset = 0;
        while (offset < attrFat->totalSize)
        {
            tmpAttrTab = tme_fat_chain_mmap(attrFat, offset, sizeof(TME_AttrTab));
            offset += sizeof(TME_AttrTab);
            if (!tmpAttrTab) {
                break;
            }
            /* 下一个 */
            tmpAttrUint = (TME_AttrUint*)calloc(1, sizeof(TME_AttrUint));
            if (!tmpAttrUint) {
                TME_ERR("calloc failed, size:%d", sizeof(TME_AttrUint));
                break;
            }
            /* 初始化节点 */
            tmpAttrUint->attrTab = tmpAttrTab;
            tmpAttrUint->timeFat = tme_fat_chain_open(fp, tmpAttrUint->attrTab->timeFatIndex, TME_FAT_UNIT_TYPE_TIME);
            tmpAttrUint->dataFat = tme_fat_chain_open(fp, tmpAttrUint->attrTab->timeFatIndex, TME_FAT_UNIT_TYPE_DATA);
            tmpAttrTab = NULL;
            /* 接入链表 */
            tmpAttrUint->next = *attrUint;
            *attrUint = tmpAttrUint;
            /* 查找父属性并关联 */
            if (tmpAttrUint->attrTab->parentId != 0)
            {
                tmpAttrUint2 = tmpAttrUint->next;
                while (tmpAttrUint2)
                {
                    if (tmpAttrUint->attrTab->parentId == tmpAttrUint2->attrTab->id) {
                        tmpAttrUint->parent = tmpAttrUint2;
                        break;
                    }
                    tmpAttrUint2 = tmpAttrUint2->next;
                }
            }
            /* 生成属性全名 */
            tmpAttrUint->fullName = _tme_attrFullName(tmpAttrUint);
            /* 打印属性信息 */
            TME_DEBUG("load attr: id:0x%08X parentId:0x%08X size:%d time:%d dFat:%d tFat:%d name:%s fullName:%s",
                tmpAttrUint->attrTab->id,
                tmpAttrUint->attrTab->parentId,
                tmpAttrUint->attrTab->dataSize,
                tmpAttrUint->attrTab->durationMs,
                tmpAttrUint->attrTab->dataFatIndex,
                tmpAttrUint->attrTab->timeFatIndex,
                tmpAttrUint->attrTab->shortName,
                tmpAttrUint->fullName);
        }
        /* 存在内存分配失败情况 */
        if (tmpAttrTab) {
            tme_fat_chain_unmmap((void*)tmpAttrTab);
        }
        
        result = 0;
    } while(0);
    return result;
}

static TME_AttrUint* _tme_attrGetAttrUint(void* handle, int32_t attrId)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    /* 遍历链表,匹配id */
    TME_AttrUint* attrUint = api->attrUint;
    while (attrUint)
    {
        if (attrId == attrUint->attrTab->id) {
            break;
        }
        attrUint = attrUint->next;
    }
    return attrUint;
}

static TME_AttrUint* _tme_attrGetAttrUintByName(void* handle, const char* attrName)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    /* 遍历链表,匹配名称 */
    TME_AttrUint* attrUint = api->attrUint;
    while (attrUint)
    {
        /* 匹配全名 */
        if (tme_utils_strcmp(attrName, attrUint->fullName, TME_ATTR_FULL_NAME_SPILT) == 0) {
            break;
        }
        attrUint = attrUint->next;
    }
    return attrUint;
}

static TME_AttrUint* _tme_attrAdd(void* handle, const char* _attrName, int32_t checkUnique)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    TME_AttrUint* attrUint = NULL;
    int32_t result = -1;
    do
    {
        /* 只读模式 */
        if (api->fp->isReadOnly) {
            TME_ERR("can not add attr on read only mode");
            break;
        }
        /* 当前属性名称定位 */
        const char* attrName = _attrName;
        /* 查找父属性&查重 */
        TME_AttrUint* attrUintParent = NULL;
        TME_AttrUint* tmpAttrUint = api->attrUint;
        int32_t cmpRet = -1;
        while (tmpAttrUint)
        {
            cmpRet = tme_utils_strcmp(_attrName, tmpAttrUint->fullName, TME_ATTR_FULL_NAME_SPILT);
            /* 定位到父属性 */
            if (cmpRet == 1) {
                attrUintParent = tmpAttrUint;
                attrName = _attrName + strlen(tmpAttrUint->fullName) + 1;
                break;
            }
            /* 出现重名属性 */
            else if (cmpRet == 0 && checkUnique) {
                break;
            }
            tmpAttrUint = tmpAttrUint->next;
        }
        if (cmpRet == 0 && checkUnique) {
            TME_ERR("attr \"%s\" repeated", _attrName);
            break;
        }
        /* 初始化链表节点 */
        attrUint = (TME_AttrUint*)calloc(1, sizeof(TME_AttrUint));
        if (!attrUint) {
            TME_ERR("calloc failed, size:%d", sizeof(TME_AttrUint));
            break;
        }
        attrUint->timeFat = tme_fat_chain_open(api->fp, -1, TME_FAT_UNIT_TYPE_TIME);
        if (!attrUint->timeFat) {
            TME_ERR("create attr \"%s\" time fat failed", _attrName);
            break;
        }
        attrUint->dataFat = tme_fat_chain_open(api->fp, -1, TME_FAT_UNIT_TYPE_DATA);
        if (!attrUint->dataFat) {
            TME_ERR("create attr \"%s\" data fat failed", _attrName);
            break;
        }
        attrUint->parent = attrUintParent;
        /* 初始化属性内容 */
        TME_AttrTab attrTab = {0};
        attrTab.id = api->fp->head->attrIdleId++;
        attrTab.parentId = attrUintParent ? attrUintParent->attrTab->id : 0;
        attrTab.dataFatIndex = attrUint->timeFat->fatBeginIndex;
        attrTab.timeFatIndex = attrUint->dataFat->fatBeginIndex;
        attrTab.nameLength = strlen(attrName);
        attrTab.nameOffset = 0;
        attrTab.durationMs = 0;
        attrTab.dataSize = 0;
        snprintf(attrTab.shortName, sizeof(attrTab.shortName)-1, "%s", attrName);
        /* 写入全局属性表 */
        int32_t offset = api->attrFat->totalSize;
        if (tme_fat_chain_write(api->attrFat, (const uint8_t*)&attrTab, sizeof(TME_AttrTab)) != sizeof(TME_AttrTab)) {
            TME_ERR("write attr \"%s\" fat failed", _attrName);
            break;
        }
        /* 属性表个数增加 */
        api->fp->head->attrCount += 1;
        /* 映射 */
        attrUint->attrTab = (TME_AttrTab*)tme_fat_chain_mmap(api->attrFat, offset, sizeof(TME_AttrTab));
        if (!attrUint->attrTab) {
            TME_ERR("mmap attr \"%s\" failed", _attrName);
            break;
        }
        /* 添加到属性链表 */
        attrUint->next = api->attrUint;
        api->attrUint = attrUint;
        /* 生成属性全名 */
        attrUint->fullName = _tme_attrFullName(attrUint);

        result = 0;
    } while(0);

    if (result != 0 && attrUint)
    {
        if (attrUint->attrTab) {
            tme_fat_chain_unmmap(attrUint->attrTab);
        }
        if (attrUint->timeFat) {
            tme_fat_chain_close(attrUint->timeFat);
        }
        if (attrUint->dataFat) {
            tme_fat_chain_close(attrUint->dataFat);
        }
        if (attrUint->fullName) {
            free(attrUint->fullName);
        }
        free(attrUint);
        attrUint = NULL;
    }
    return attrUint;
}

static int32_t _tme_timeWrite(TME_ApiHandle* api, TME_TimeFatNote *timeFatNote, TME_AttrUint* attrUint, int32_t dataLen)
{
    /* 可能需要更新的项 */
    uint32_t upgradeAttrValue = 0;
    uint32_t upgradeOffsetValue = 0;
    uint32_t upgradeTimeValue = 0;
    uint32_t upgradeDataValue = 0;
    /* 判断需要更新属性id */
    if (timeFatNote->cAttrId != attrUint->attrTab->id)
    {
        /* 当出现属性ID变动时,要同时更新offset和time */
        timeFatNote->cAttrId = attrUint->attrTab->id;
        timeFatNote->cFatIndex = attrUint->dataFat->fatWriteIndex;
        /* 更新属性ID */
        SET_TIME_TAB_UNIT_TYPE(upgradeAttrValue, TME_TIME_TAB_UNIT_TYPE_ATTR_DIFF);
        SET_TIME_TAB_UNIT_VALUE(upgradeAttrValue, timeFatNote->cAttrId);
        /* 更新offset */
        SET_TIME_TAB_UNIT_TYPE(upgradeOffsetValue, TME_TIME_TAB_UNIT_TYPE_OFFSET_DIFF);
        SET_TIME_TAB_UNIT_VALUE(upgradeOffsetValue, attrUint->dataFat->writeSeek);
        /* 更新time */
        timeFatNote->cDiffMs = tme_file_getDiffMs(api->fp);
        SET_TIME_TAB_UNIT_TYPE_TIME_DIFF(upgradeTimeValue);
        SET_TIME_TAB_UNIT_VALUE_TIME_DIFF(upgradeTimeValue, timeFatNote->cDiffMs);
    }
    /* 判断需要更新offset */
    if (!upgradeOffsetValue && timeFatNote->cFatIndex != attrUint->dataFat->fatWriteIndex)
    {
        timeFatNote->cFatIndex = attrUint->dataFat->fatWriteIndex;
        /* 更新offset */
        SET_TIME_TAB_UNIT_TYPE(upgradeOffsetValue, TME_TIME_TAB_UNIT_TYPE_OFFSET_DIFF);
        SET_TIME_TAB_UNIT_VALUE(upgradeOffsetValue, attrUint->dataFat->writeSeek);
    }
    /* 判断需要更新time */
    if (!upgradeTimeValue)
    {
        uint32_t newDiffMs = tme_file_getDiffMs(api->fp);
        if (timeFatNote->cDiffMs != newDiffMs)
        {
            timeFatNote->cDiffMs = newDiffMs;
            /* 更新time */
            SET_TIME_TAB_UNIT_TYPE_TIME_DIFF(upgradeTimeValue);
            SET_TIME_TAB_UNIT_VALUE_TIME_DIFF(upgradeTimeValue, timeFatNote->cDiffMs);
        }
    }
    /* 数据长度 */
    SET_TIME_TAB_UNIT_TYPE(upgradeDataValue, TME_TIME_TAB_UNIT_TYPE_DATA_DIFF);
    SET_TIME_TAB_UNIT_VALUE(upgradeDataValue, dataLen);
    /* 按优先顺序依次写入配置 */
    if (upgradeAttrValue) {
        tme_fat_chain_write(api->timeFat, (const uint8_t*)&upgradeAttrValue, 4);
    }
    if (upgradeOffsetValue) {
        tme_fat_chain_write(api->timeFat, (const uint8_t*)&upgradeOffsetValue, 4);
    }
    if (upgradeTimeValue) {
        tme_fat_chain_write(api->timeFat, (const uint8_t*)&upgradeTimeValue, 4);
    }
    if (upgradeDataValue) {
        tme_fat_chain_write(api->timeFat, (const uint8_t*)&upgradeDataValue, 4);
    }
    return 0;
}

static int32_t _tme_attrWrite(void* handle, TME_AttrUint* attrUint, const void* data, int32_t dataSize)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    int32_t result = 0;
    do
    {
        /* 写数据 */
        if (tme_fat_chain_write(attrUint->dataFat, (const uint8_t*)data, dataSize) != dataSize) {
            break;
        }
        /* 更新数据长度和时长信息 */
        attrUint->attrTab->dataSize += dataSize;
        attrUint->attrTab->durationMs += 0;
        /* 写总览时间表 */
        _tme_timeWrite(api, &api->timeFatNoteWrite, attrUint, dataSize);

        result = dataSize;
    } while(0);
    return result;
}

static int32_t _tme_attrRead(void* handle, TME_AttrUint* attrUint, void* data, int32_t dataSize, int32_t *offset)
{
    int32_t ret = -1;
    do
    {
        /* offset不一致则seek */
        if (offset && *offset != attrUint->dataFat->readSeek)
        {
            ret = tme_fat_chain_readSeek(attrUint->dataFat, *offset);
            if (ret != 0) {
                break;
            }
        }
        /* 读数据 */
        ret = tme_fat_chain_read(attrUint->dataFat, (uint8_t*)data, dataSize);
        /* 更新offset */
        if (offset) {
            *offset = attrUint->dataFat->readSeek;
        }
    } while(0);
    return ret;
}

static void* _tme_open(const char* file, int32_t isReadOnly)
{
    int32_t result = -1;
    TME_ApiHandle* api = (TME_ApiHandle*)calloc(1, sizeof(TME_ApiHandle));
    do
    {
        if (!api) {
            TME_ERR("calloc failed, size:%d", sizeof(TME_ApiHandle));
            break;
        }
        /* 打开文件 */
        api->fp = tme_file_open(file, isReadOnly ? 'r' : 'w');
        if (!api->fp) {
            TME_ERR("tme_file_open mode:w failed, file:%s", file);
            break;
        }
        /* 打开总属性表句柄 */
        api->attrFat = tme_fat_chain_open(
            api->fp,
            api->fp->head->attrFatIndex,
            TME_FAT_UNIT_TYPE_ATTR);
        if (!api->attrFat) {
            TME_ERR("open attr chain fat failed, file:%s index:%d", file, api->fp->head->attrNameFatIndex);
            break;
        }
        /* 打开总览时间表句柄 */
        api->timeFat = tme_fat_chain_open(
            api->fp,
            api->fp->head->timeFatIndex,
            TME_FAT_UNIT_TYPE_TIME);
        if (!api->timeFat) {
            TME_ERR("open time chain fat failed, file:%s index:%d", file, api->fp->head->timeFatIndex);
            break;
        }
        /* 加载全属性 */
        _tme_load_attrUint(api->fp, api->attrFat, &api->attrUint);
        /* 加载全属性名称 */
        ;
        result = 0;
    } while(0);

    if (result != 0 && api) {
        tme_close(api);
        api = NULL;
    }
    return api;
}

/* -------------------- 公共api -------------------- */

void* tme_open(const char* file)
{
    return _tme_open(file, 0);
}

void* tme_openReadOnly(const char* file)
{
    return _tme_open(file, 1);
}

void tme_close(void* handle)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    if (!api) {
        return;
    }
    /* 回收属性链表 */
    TME_AttrUint* unitCurr = api->attrUint;
    TME_AttrUint* unitNext = NULL;
    while (unitCurr)
    {
        unitNext = unitCurr->next;
        if (unitCurr->attrTab) {
            tme_fat_chain_unmmap(unitCurr->attrTab);
        }
        if (unitCurr->timeFat) {
            tme_fat_chain_close(unitCurr->timeFat);
        }
        if (unitCurr->dataFat) {
            tme_fat_chain_close(unitCurr->dataFat);
        }
        if (unitCurr->fullName) {
            free(unitCurr->fullName);
        }
        free(unitCurr);
        unitCurr = unitNext;
    }
    api->attrUint = NULL;
    /* 关闭fat句柄 */
    if (api->timeFat) {
        tme_fat_chain_close(api->timeFat);
        api->timeFat = NULL;
    }
    if (api->attrFat) {
        tme_fat_chain_close(api->attrFat);
        api->attrFat = NULL;
    }
    /* 关闭文件 */
    if (api->fp) {
        tme_file_close(api->fp);
        api->fp = NULL;
    }
    free(api);
}

int32_t tme_info(void* handle, char* buff, int32_t buffSize)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    if (!api) {
        return 0;
    }
    /* 打印文件信息 */
    snprintf(buff, buffSize,
        "fileSize: %d \r\n"
        "beginTime: %04d.%02d.%02d %02d:%02d:%02d.%03d \r\n"
        "diffTime: %02d:%02d:%02d.%03d \r\n"
        "durationTime: %02d:%02d:%02d.%03d \r\n"
        "fatUnitOnFat: %d \r\n"
        "fatUnitToBlockSize: %d \r\n"
        "fatUnitOnUse: %d \r\n"
        "fatTabSize: %d \r\n"
        "fatTabOnUse: %d \r\n"
        "attrCount: %d \r\n"
        "attrIdleId: %d \r\n"
        "isReadOnly: %d \r\n"
        "isExtend: %d \r\n",
        api->fp->head->fileSize,
        api->fp->head->beginYear,
        api->fp->head->beginMonth,
        api->fp->head->beginDay,
        api->fp->head->beginMs / 1000 / 60 / 60,
        api->fp->head->beginMs / 1000 / 60 % 60,
        api->fp->head->beginMs / 1000 % 60,
        api->fp->head->beginMs % 1000,
        api->fp->diffTickMs / 1000 / 60 / 60,
        api->fp->diffTickMs / 1000 / 60 % 60,
        api->fp->diffTickMs / 1000 % 60,
        api->fp->diffTickMs % 1000,
        api->fp->head->durationMs / 1000 / 60 / 60,
        api->fp->head->durationMs / 1000 / 60 % 60,
        api->fp->head->durationMs / 1000 % 60,
        api->fp->head->durationMs % 1000,
        api->fp->head->fatUnitNumber,
        api->fp->head->fatUnitBlockSize,
        api->fp->head->fatIdleIndex,
        api->fp->head->fatSize,
        api->fp->head->fatCount,
        api->fp->head->attrCount,
        api->fp->head->attrIdleId,
        api->fp->isReadOnly,
        api->fp->isExtend);
}

int32_t tme_isReadOnly(void* handle)
{
    return ((TME_ApiHandle*)handle)->fp->isReadOnly;
}

int32_t tme_attrGetId(void* handle, const char* attrName)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUintByName(handle, attrName);
    return attrUint ? attrUint->attrTab->id : (-1);
}

int32_t tme_attrGetIdLoop(void* handle, int32_t count)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    if (!api) {
        return -1;
    }
    TME_AttrUint* attrUint = api->attrUint;
    while (attrUint && count > 0) {
        count -= 1;
        attrUint = attrUint->next;
    }
    return attrUint ? attrUint->attrTab->id : (-1);
}

int32_t tme_attrGetName(void* handle, int32_t attrId, char* buff, int32_t buffSize)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUint(handle, attrId);
    if (attrUint) {
        snprintf(buff, buffSize, "%s", attrUint->attrTab->shortName);
        return 0;
    }
    return -1;
}

int32_t tme_attrGetFullName(void* handle, int32_t attrId, char* buff, int32_t buffSize)
{
    TME_ApiHandle* api = (TME_ApiHandle*)handle;
    /* 遍历链表,匹配id */
    TME_AttrUint* attrUint = api->attrUint;
    while (attrUint)
    {
        if (attrId == attrUint->attrTab->id) {
            _tme_attrNameSpilt(attrUint, buff, buffSize);
            break;
        }
        attrUint = attrUint->next;
    }
    return attrUint ? 0 : (-1);
}

/* -------------------- 写数据api -------------------- */

int32_t tme_attrAdd(void* handle, const char* attrName, int32_t checkUnique)
{
    TME_AttrUint* attrUint = _tme_attrAdd(handle, attrName, checkUnique);
    return attrUint ? attrUint->attrTab->id : (-1);
}

int32_t tme_attrWrite(void* handle, int32_t attrId, const void* data, int32_t dataSize)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUint(handle, attrId);
    if (!attrUint) {
        TME_ERR("attr id 0x%08X not found", attrId);
        return 0;
    }
    return _tme_attrWrite(handle, attrUint, data, dataSize);
}

int32_t tme_attrWriteByName(void* handle, const char* attrName, const void* data, int32_t dataSize)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUintByName(handle, attrName);
    if (!attrUint)
    {
        /* 不存在则新建 */
        attrUint = _tme_attrAdd(handle, attrName, 0);
        if (!attrUint) {
            TME_ERR("add attr \"%s\" failed", attrName);
            return 0;
        }
    }
    return _tme_attrWrite(handle, attrUint, data, dataSize);
}

/* -------------------- 读数据api -------------------- */

int32_t tme_attrRead(void* handle, int32_t attrId, void* data, int32_t dataSize, int32_t *offset)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUint(handle, attrId);
    return attrUint ? _tme_attrRead(handle, attrUint, data, dataSize, offset) : (-1);
}

int32_t tme_attrReadByName(void* handle, const char* attrName, void* data, int32_t dataSize, int32_t *offset)
{
    TME_AttrUint* attrUint = _tme_attrGetAttrUintByName(handle, attrName);
    return attrUint ? _tme_attrRead(handle, attrUint, data, dataSize, offset) : (-1);
}

int32_t tme_attrSizeOf(void* handle, int32_t attrId)
{
    if (attrId < 0) {
        return attrId;
    }
    TME_AttrUint* attrUint = _tme_attrGetAttrUint(handle, attrId);
    if (!attrUint) {
        return -1;
    }
    return attrUint->dataFat->totalSize;
}

/* -------------------- 读时间表api -------------------- */

static int32_t _tme_timeNodeSeek(void* handle, TME_TimeFatNote* timeFatNote, int32_t *offset)
{
    ;
}

int32_t tme_timeNodeRead(void* handle, TME_TimeNode** node, int32_t nodeMax, int32_t singleDurationMs, int32_t totalDurationMs, int32_t *offset)
{
    return 0;
}

void tme_timeNodeRelease(TME_TimeNode** _node)
{
    if (!_node) {
        return;
    }
    TME_TimeNode* node = *_node;
    do
    {
        if (!node) {
            break;
        }
        /* 移动到头部 */
        while (node->prev)
        {
            // node->prev->next = node; /* 链表修复 */
            node = node->prev;
        }
        /* 依次释放 */
        TME_TimeNode* nodeTmp = NULL;
        while (node)
        {
            nodeTmp = node->next;
            free(node);
            node = nodeTmp;
        }
    } while(0);
    *_node = NULL;
}

int32_t tme_timeNodeTimeOf(void* handle, int32_t offset)
{
    return 0;
}

int32_t tme_timeNodeSeek(void* handle, int32_t offsetTimeMs, int32_t* offset)
{
    return 0;
}
